# -*- coding: utf-8 -*-
import KBEngine
import IKernel
import time
import random
import xml.dom.minidom
import ConstDef
import Functor
import MailDef
import MsgDef
import time
import datetime
import LogDef

from KBEDebug import *

class MailModule:
	def __init__(self):
		self.mailsCfg = {}

	def init(self, isReload):
		IKernel.Instance().registerFunc("MailModule.onClientMsg", self.onClientMsg)
		IKernel.Instance().registerFunc("MailModule.onCellMsg", self.onCellMsg)

		IKernel.Instance().addIntMsgCallback(MsgDef.CLIENT2CELL_MAIL_MSG, "MailModule.onClientMsg")
		IKernel.Instance().addIntMsgCallback(MsgDef.CELL2CELL_MAIL_MSG, "MailModule.onCellMsg")

		self.loadRes()

	def loadRes(self):
		self.mailsCfg = {}

		path = KBEngine.getResFullPath("cfg/mail_cfg.xml")
		#打开xml文档
		dom = xml.dom.minidom.parse(path)
		#得到文档元素对象
		root = dom.documentElement

		propEle = root.getElementsByTagName("property")
		for prop in propEle :
			id = int(prop.getAttribute("id"));
			if id == 0 :
				continue

			mailCfg = {}
			for eleName, v in prop._attrs.items():
				value = v.value
				if value.isdigit():
					value = int(v.value)
				mailCfg[eleName] = value

			self.mailsCfg[id] = mailCfg

	def end(self):
		pass

	def sendMail(self, senderEntityID, receiverUid, receiverName, mailCfgID):
		if receiverUid == 0 and receiverName == "":
			assert(False)
			return False

		mailCfg = self.mailsCfg.get(mailCfgID)
		if mailCfg == None:
			assert(False)
			# 配置文件错误
			return False

		senderEntity = KBEngine.entities.get(senderEntityID)
		senderUid = senderEntity.uid
		senderName = senderEntity.name
		title = mailCfg["title"]
		content = mailCfg["content"]
		attachment = mailCfg["attachment"]
		logID = mailCfg["logID"]

		dt = datetime.datetime.now()
		timeStr = dt.strftime("%Y-%m-%d %H:%M:%S")
		command = "insert into tbl_mail \
			(sm_state, sm_senderUid, sm_senderName, sm_receiverUid,sm_receiverName, sm_title, sm_content, sm_attachment, sm_sendTime, sm_log) \
			values({},{},{},{},{},{},{},{},{})".format(MailDef.State.Unread, senderUid, senderName, \
			receiverUid, receiverName, title, content, attachment, timeStr, logID)

		receiverEntityID = KBEngine.globalData.get(receiverUid)
		if receiverEntityID == None:
			return

		msg = []
		msg.append(MsgDef.CELL2CELL_MAIL_MSG)
		msg.append(MailDef.SUB_MSG_NOTIFY_NEW_MAIL)
		# 这里发消息的原因是：防止发送者实体和接受者实体不在同一个cellapp中
		IKernel.Instance().sendCellMsg(receiverEntityID, msg)

	def onCellMsg(self, senderEntityID, receiverEntityID, args):
		dispatcher = {
			MailDef.SUB_MSG_NOTIFY_NEW_MAIL : self.notifyNewMail,
		}
		submsg = args[1]
		funcAddr = dispatcher.get(submsg)
		if funcAddr == None:
			return
		funcAddr(senderEntityID, receiverEntityID, args)

	def notifyNewMail(self, senderEntityID, receiverEntityID, args):
		receiverEntity = KBEngine.entities.get(receiverEntityID)
		receiverEntity.isReceiveNewMail = 1

	def onClientMsg(self, senderEntityID, receiverEntityID, args):
		dispatcher = {
			MailDef.SUB_MSG_GET_MAIL_DATA : self.reqMailData,
			MailDef.SUB_MSG_OP_MAIL : self.reqOpMail,
		}
		submsg = args[1]
		funcAddr = dispatcher.get(submsg)
		if funcAddr == None:
			return
		funcAddr(receiverEntityID, args)

	def reqMailData(self, playerEntityID, args):
		cb = Functor.Functor(self.sqlCallback, playerEntityID)
		playerEntity = KBEngine.entities.get(playerEntityID)
		playerEntity.isReceiveNewMail = 0

		command = "select * from tbl_mail where sm_state!={} and (sm_receiverUid={} or sm_receiverName='{}') limit 50".format( \
			MailDef.State.Deleted, playerEntity.uid, playerEntity.name)
		KBEngine.executeRawDatabaseCommand(command, cb)

	def sqlCallback(self, playerEntityID, result, rows, insertid, error):
		playerEntity = KBEngine.entities.get(playerEntityID)
		if(error != None):
			ERROR_MSG("sqlCallback has error:%s" % (error))

		if result == None or len(result) == 0:
			return

		playerEntity.mailData = {}

		msg = []
		msg.append(MsgDef.CELL2CLIENT_MAIL_MSG)
		msg.append(MailDef.SUB_MSG_GET_MAIL_DATA)
		# 有几行数据
		msg.append(0)
		for rowData in result:
			id = int(rowData[0].decode('utf-8'))
			state = int(rowData[2].decode('utf-8'))
			senderUid = int(rowData[3].decode('utf-8'))
			senderName = str(rowData[4].decode('utf-8'))
			receiverUid = int(rowData[5].decode('utf-8'))
			receiverName = str(rowData[6].decode('utf-8'))
			title = str(rowData[7].decode('utf-8'))
			content = str(rowData[8].decode('utf-8'))
			attachment = str(rowData[9].decode('utf-8'))
			sendTime = str(rowData[10].decode('utf-8'))

			msg.append(id)
			msg.append(state)
			msg.append(senderUid)
			msg.append(senderName)
			msg.append(receiverUid)
			msg.append(title)
			msg.append(content)
			msg.append(attachment)
			msg.append(sendTime)
			msg[2] = msg[2] + 1

			# 邮件信息临时缓存到玩家身上
			playerEntity.mailData[id] = [state, attachment]

		IKernel.Instance().sendClientMsg(playerEntityID, msg)

	def reqOpMail(self, playerEntityID, args):
		opType = args[2]
		if opType <= MailDef.State.Invalid or opType >= MailDef.State.Max:
			return

		mailIDNum = args[3]
		if len(args) < mailIDNum + 4:
			return

		playerEntity = KBEngine.entities.get(playerEntityID)
		changedMail = {}
		for i in range(0, mailIDNum):
			mailID = args[4+i]
			mailInfo = playerEntity.mailData.get(mailID)
			if mailInfo == None:
				continue

			state = mailInfo[0]
			attachment = mailInfo[1]
			if opType <= state:# 操作不能逆行
				continue

			#有可领取的附件不能删除
			if state < MailDef.State.GetAttachment and attachment != "" and opType == MailDef.State.Deleted:
				continue

			if opType == MailDef.State.Deleted:
				playerEntity.mailData.pop(mailID)
			else:
				mailInfo[0] = opType

			changedMail[mailID] = attachment

		if len(changedMail) == 0:
			return

		from logic import ModuleMgr
		itemModule = ModuleMgr.Instance().getModule("ItemModule")

		command = "update chess.tbl_mail set sm_state={} where ".format(opType)
		whereSubSql = ""

		for mailID, attachment in changedMail.items():
			if whereSubSql != "":
				whereSubSql = whereSubSql + " or "
			whereSubSql = whereSubSql + " id={} ".format(mailID)

			if opType != MailDef.State.GetAttachment:
				continue

			strItemsNum = attachment.split(";")
			for i in range(0, len(strItemsNum)):
				strItemNum = strItemsNum[i].split(":")
				itemID = int(strItemNum[0])
				itemNum = int(strItemNum[1])
				if itemID == 0 or itemNum == 0:
					continue
				itemModule.addItem(playerEntityID, itemID, itemNum, LogDef.ADD_LOG_GET_ITEM_FROM_MAIL)

		command = command + whereSubSql
		KBEngine.executeRawDatabaseCommand(command)
